home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / doc / sg3-utils / examples / sg_excl.c < prev    next >
Encoding:
C/C++ Source or Header  |  2005-12-20  |  5.9 KB  |  198 lines

  1. #include <unistd.h>
  2. #include <fcntl.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <string.h>
  6. #include <errno.h>
  7. #include <sys/ioctl.h>
  8. #include <sys/types.h>
  9. #include <sys/stat.h>
  10. #include "sg_lib.h"
  11. #include "sg_io_linux.h"
  12.  
  13. /* This is a simple program that tests the O_EXCL flag in sg while
  14.    executing a SCSI INQUIRY command and a
  15.    TEST UNIT READY command using the SCSI generic (sg) driver
  16.  
  17. *  Copyright (C) 2003 D. Gilbert
  18. *  This program is free software; you can redistribute it and/or modify
  19. *  it under the terms of the GNU General Public License as published by
  20. *  the Free Software Foundation; either version 2, or (at your option)
  21. *  any later version.
  22.  
  23.    Invocation: sg_simple1 [-x] <sg_device>
  24.  
  25.    Version 03.57 (20020226)
  26.  
  27. 6 byte INQUIRY command:
  28. [0x12][   |lu][pg cde][res   ][al len][cntrl ]
  29.  
  30. 6 byte TEST UNIT READY command:
  31. [0x00][   |lu][res   ][res   ][res   ][res   ]
  32.  
  33. */
  34.  
  35. #define INQ_REPLY_LEN 96
  36. #define INQ_CMD_LEN 6
  37. #define TUR_CMD_LEN 6
  38.  
  39. #define EBUFF_SZ 256
  40.  
  41. #define ME "sg_excl: "
  42.  
  43. int main(int argc, char * argv[])
  44. {
  45.     int sg_fd, k, ok /*, sg_fd2 */;
  46.     unsigned char inqCmdBlk [INQ_CMD_LEN] =
  47.                                 {0x12, 0, 0, 0, INQ_REPLY_LEN, 0};
  48.     unsigned char turCmdBlk [TUR_CMD_LEN] =
  49.                                 {0x00, 0, 0, 0, 0, 0};
  50.     unsigned char inqBuff[INQ_REPLY_LEN];
  51.     sg_io_hdr_t io_hdr;
  52.     char * file_name = 0;
  53.     char ebuff[EBUFF_SZ];
  54.     unsigned char sense_buffer[32];
  55.     int do_extra = 0;
  56.  
  57.     for (k = 1; k < argc; ++k) {
  58.         if (0 == memcmp("-x", argv[k], 2))
  59.             do_extra = 1;
  60.         else if (*argv[k] == '-') {
  61.             printf("Unrecognized switch: %s\n", argv[k]);
  62.             file_name = 0;
  63.             break;
  64.         }
  65.         else if (0 == file_name)
  66.             file_name = argv[k];
  67.         else {
  68.             printf("too many arguments\n");
  69.             file_name = 0;
  70.             break;
  71.         }
  72.     }
  73.     if (0 == file_name) {
  74.         printf("Usage: 'sg_simple1 [-x] <sg_device>'\n");
  75.         return 1;
  76.     }
  77.  
  78.     /* N.B. An access mode of O_RDWR is required for some SCSI commands */
  79.     if ((sg_fd = open(file_name, O_RDWR | O_EXCL | O_NONBLOCK)) < 0) {
  80.         snprintf(ebuff, EBUFF_SZ, ME "error opening file: %s", file_name);
  81.         perror(ebuff);
  82.         return 1;
  83.     }
  84.     /* Just to be safe, check we have a new sg device by trying an ioctl */
  85.     if ((ioctl(sg_fd, SG_GET_VERSION_NUM, &k) < 0) || (k < 30000)) {
  86.         printf(ME "%s doesn't seem to be an new sg device\n",
  87.                file_name);
  88.         close(sg_fd);
  89.         return 1;
  90.     }
  91. #if 0
  92.     if ((sg_fd2 = open(file_name, O_RDWR | O_EXCL)) < 0) {
  93.         snprintf(ebuff, EBUFF_SZ,
  94.                  ME "error opening file: %s a second time", file_name);
  95.         perror(ebuff);
  96.         return 1;
  97.     } else {
  98.         printf(ME "second open of %s in violation of O_EXCL\n", file_name);
  99.         close(sg_fd2);
  100.     }
  101. #endif
  102.  
  103.     /* Prepare INQUIRY command */
  104.     memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
  105.     io_hdr.interface_id = 'S';
  106.     io_hdr.cmd_len = sizeof(inqCmdBlk);
  107.     /* io_hdr.iovec_count = 0; */  /* memset takes care of this */
  108.     io_hdr.mx_sb_len = sizeof(sense_buffer);
  109.     io_hdr.dxfer_direction = SG_DXFER_FROM_DEV;
  110.     io_hdr.dxfer_len = INQ_REPLY_LEN;
  111.     io_hdr.dxferp = inqBuff;
  112.     io_hdr.cmdp = inqCmdBlk;
  113.     io_hdr.sbp = sense_buffer;
  114.     io_hdr.timeout = 20000;     /* 20000 millisecs == 20 seconds */
  115.     /* io_hdr.flags = 0; */     /* take defaults: indirect IO, etc */
  116.     /* io_hdr.pack_id = 0; */
  117.     /* io_hdr.usr_ptr = NULL; */
  118.  
  119.     if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
  120.         perror(ME "Inquiry SG_IO ioctl error");
  121.         close(sg_fd);
  122.         return 1;
  123.     }
  124.  
  125.     /* now for the error processing */
  126.     ok = 0;
  127.     switch (sg_err_category3(&io_hdr)) {
  128.     case SG_LIB_CAT_CLEAN:
  129.         ok = 1;
  130.         break;
  131.     case SG_LIB_CAT_RECOVERED:
  132.         printf("Recovered error on INQUIRY, continuing\n");
  133.         ok = 1;
  134.         break;
  135.     default: /* won't bother decoding other categories */
  136.         sg_chk_n_print3("INQUIRY command error", &io_hdr, 1);
  137.         break;
  138.     }
  139.  
  140.     if (ok) { /* output result if it is available */
  141.         char * p = (char *)inqBuff;
  142.         int f = (int)*(p + 7);
  143.         printf("Some of the INQUIRY command's results:\n");
  144.         printf("    %.8s  %.16s  %.4s  ", p + 8, p + 16, p + 32);
  145.         printf("[wide=%d sync=%d cmdque=%d sftre=%d]\n",
  146.                !!(f & 0x20), !!(f & 0x10), !!(f & 2), !!(f & 1));
  147.         /* Extra info, not necessary to look at */
  148.         if (do_extra)
  149.             printf("INQUIRY duration=%u millisecs, resid=%d, msg_status=%d\n",
  150.                    io_hdr.duration, io_hdr.resid, (int)io_hdr.msg_status);
  151.     }
  152.  
  153.  
  154.     /* Prepare TEST UNIT READY command */
  155.     memset(&io_hdr, 0, sizeof(sg_io_hdr_t));
  156.     io_hdr.interface_id = 'S';
  157.     io_hdr.cmd_len = sizeof(turCmdBlk);
  158.     io_hdr.mx_sb_len = sizeof(sense_buffer);
  159.     io_hdr.dxfer_direction = SG_DXFER_NONE;
  160.     io_hdr.cmdp = turCmdBlk;
  161.     io_hdr.sbp = sense_buffer;
  162.     io_hdr.timeout = 20000;     /* 20000 millisecs == 20 seconds */
  163.  
  164.     if (ioctl(sg_fd, SG_IO, &io_hdr) < 0) {
  165.         perror(ME "Test Unit Ready SG_IO ioctl error");
  166.         close(sg_fd);
  167.         return 1;
  168.     }
  169.  
  170.     /* now for the error processing */
  171.     ok = 0;
  172.     switch (sg_err_category3(&io_hdr)) {
  173.     case SG_LIB_CAT_CLEAN:
  174.         ok = 1;
  175.         break;
  176.     case SG_LIB_CAT_RECOVERED:
  177.         printf("Recovered error on Test Unit Ready, continuing\n");
  178.         ok = 1;
  179.         break;
  180.     default: /* won't bother decoding other categories */
  181.         sg_chk_n_print3("Test Unit Ready command error", &io_hdr, 1);
  182.         break;
  183.     }
  184.  
  185.     if (ok)
  186.         printf("Test Unit Ready successful so unit is ready!\n");
  187.     else
  188.         printf("Test Unit Ready failed so unit may _not_ be ready!\n");
  189.  
  190.     if (do_extra)
  191.         printf("TEST UNIT READY duration=%u millisecs, resid=%d, msg_status=%d\n",
  192.                io_hdr.duration, io_hdr.resid, (int)io_hdr.msg_status);
  193.  
  194.     sleep(60);
  195.     close(sg_fd);
  196.     return 0;
  197. }
  198.